<?php declare(strict_types=1);


namespace App\Services\Pay\GuoTonXinYi;

use App\Api\Controllers\Cmbc\BaseController as base;
use App\Api\Controllers\Config\CcbConfigController;
use App\Common\PaySuccessAction;
use App\Common\RefundSuccessAction;
use App\Exceptions\BizException;
use App\Models\CommonConfigs;
use App\Models\MerchantWalletDetail;
use App\Models\Order;
use App\Models\RefundOrder;
use App\Models\RefundOrderDoing;
use App\Models\Store;
use App\Models\UserWalletDetail;
use App\Services\Store\StoreMchService;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;

class BizService
{

    public static function gtxy_public(array $data_insert, array $data, $that): string
    {
//读取配置
        $store_id = $data['store_id'];
        $store_pid = $data['store_pid'];
        $merchant_id = $data['merchant_id'];
        $total_amount = (string)$data['total_amount'];
        $ways_type = $data['ways_type'];
        $store_name = $data['store_name'];
        $config_id = $data['config_id'];
        $tg_user_id = $data['tg_user_id'];
        $code = $data['code'];
        $company = $data["company"] ?? "gtxy";
        try {
            list($mchNo, $config) = Config::config($store_id, $config_id, $company);
        } catch (\Exception $e) {
            return json_encode([
                "status" => 2,
                "message" => $e->getMessage()
            ]);
        }
        $out_trade_no = $data['out_trade_no'];
        //入库参数
        $data_insert['out_trade_no'] = $out_trade_no;
        $data_insert['ways_type'] = $data['ways_type'];
        $data_insert['ways_type_desc'] = $data['ways_type_desc'];
        $data_insert['ways_source'] = $data['ways_source'];
        $data_insert['company'] = $data['company'];
        $data_insert['ways_source_desc'] = $data['ways_source_desc'];
        $data_insert['other_no'] = $data['other_no'] ?? "";

        $insert_re = $that->insert_day_order($data_insert);
        if (!$insert_re) {
            throw new \Exception("订单未入库");
        }
        //在这里引入国通支付
        $resultVo = Pay::scanByMerchant([
            "agetId" => $config->platform_id,
            "custId" => $mchNo,
            "public_key" => $config->public_key,
        ],
            $out_trade_no,
            [
                "code" => $code,
                "ways_source" => $data["ways_source"],
                "total_amount" => $total_amount,
                "store_address" => $data["store_address"] ?? ""
            ],
            $data["couponDetail"] ?? "");
        $return = [
            "status" => 0,
            "message" => $resultVo->getMsg(),
            "data" => $resultVo->getData()
        ];
        //将强类型vo-> return 中
        if ($resultVo->getCode() == $resultVo->codeMap["ok"]) {
            //请求成功
            /*
            "pay_status" => $pay_status,
            "out_trade_no" => $out_trade_no,
            "order_no" => $resultArray["data"]["orderNo"] ?? "",//orderNo国通平台订单号
            'trade_no' => $resultArray["data"]["torderNo"] ?? "",//torderNo 微信/支付宝（目的通道流水号），银联（官方订单号）可用于退款
            "custFee" => $resultArray["data"]["custFee"] ?? "", //商户交易实收手续费
            "oldFee" => $resultArray["data"]["oldFee"] ?? "",//应收手续费
            "pay_time" => $resultArray["data"]["orderTime"] ?? "",//订单完成时间 yyyyMMddHHmmss
            "cardType" => $resultArray["data"]["cardType"] ?? "",//01借记卡、 02贷记卡、03其他
            */
            $status = 2;
            if ($resultVo->getData()["pay_status"] == 1) {
                \App\Common\PaySuccessAction::addCoupon($out_trade_no, $resultVo->getData()["promotionDetail"] ?? "", 'pay');
                $status = 1;
            } elseif ($resultVo->getData()["pay_status"] == 2) {
                $status = 2;
            } elseif ($resultVo->getData()["pay_status"] == 3) {
                $status = 3;
            }
            $return = [
                "status" => $status,
                "message" => $resultVo->getMsg(),
                "data" => $resultVo->getData()
            ];
        } else if ($resultVo->getCode() == $resultVo->codeMap["failed"]) {
            $return = [
                "status" => 0,
                "message" => $resultVo->getMsg(),
                "data" => $resultVo->getData()
            ];
        }
        //写入日志
        Log::channel("gtxy")->info("biz_return", $return);
        //返回支付成功
        if ($return['status'] == 1) {
//            $trade_no = $return['data']['trade_no'] ?? "";
            $trade_no = $return['data']['other_no'] ?? "";
            $user_info = $return["data"]["openId"] ?? "";;
            $pay_time = date('Y-m-d H:i:s', time());
            $buyer_pay_amount = $total_amount;
            $buyer_pay_amount = number_format((float)$buyer_pay_amount, 2, '.', '');
            $buyer_logon_id = $return["data"]["openId"] ?? "";

            $update_data = [
                'trade_no' => $trade_no,
//                "other_no" => $other_no,
                'buyer_id' => $user_info,
                'buyer_logon_id' => $buyer_logon_id,
                'status' => '1',
                'pay_status_desc' => '支付成功',
                'pay_status' => 1,
                'payment_method' => '',
                'pay_time' => $pay_time,
                'buyer_pay_amount' => $buyer_pay_amount, //用户实际支付
            ];
            $that->update_day_order($update_data, $out_trade_no);

            //支付成功后的动作
            $data = [
                'ways_type' => $data['ways_type'],
                'ways_type_desc' => $data['ways_type_desc'],
                'company' => $data_insert['company'],
                'source_type' => '', //返佣来源
                'source_desc' => 'gtxy', //返佣来源说明
                'total_amount' => $total_amount,
//                'other_no' => $other_no,
                'out_trade_no' => $out_trade_no,
                'rate' => $data_insert['rate'],
                'fee_amount' => $data_insert['fee_amount'],
                'merchant_id' => $merchant_id,
                'store_id' => $store_id,
                'user_id' => $tg_user_id,
                'config_id' => $config_id,
                'store_name' => $store_name,
                'ways_source' => $data['ways_source'],
                'pay_time' => $pay_time,
                'device_id' => isset($data['device_id']) ? $data['device_id'] : "",
            ];
            PaySuccessAction::action($data);

            return json_encode([
                'status' => 1,
                'pay_status' => '1',
                'message' => '支付成功',
                'data' => [
                    'out_trade_no' => $out_trade_no,
                    'ways_type' => $ways_type,
                    'total_amount' => $total_amount,
                    'store_id' => $store_id,
                    'store_name' => $store_name,
                    'config_id' => $config_id,
                    'pay_time' => $pay_time,
                    'trade_no' => $trade_no,
                    'ways_source' => $data['ways_source'],
                    "other_no" => $data['other_no']??"",
                ]
            ]);
        }

        //正在支付
        if ($return['status'] == 2) {
            return json_encode([
                'status' => 1,
                'pay_status' => '2',
                'message' => '正在支付',
                'data' => [
                    'out_trade_no' => $out_trade_no,
                    'ways_type' => $ways_type,
                    'ways_source' => $data['ways_source'],
                    'total_amount' => $total_amount,
                    'store_id' => $store_id,
                    'store_name' => $store_name,
                    'config_id' => $config_id,
                    "other_no" => $data['other_no']??"",
                ]
            ]);
        }

        //支付失败
        if ($return['status'] == 3) {
            return json_encode([
                'status' => 2,
                'pay_status' => '3',
                'message' => '支付失败',
                'data' => [
                    'out_trade_no' => $out_trade_no,
                    'ways_type' => $ways_type,
                    'ways_source' => $data['ways_source'],
                    'total_amount' => $total_amount,
                    'store_id' => $store_id,
                    'store_name' => $store_name,
                    'config_id' => $config_id,
                    "other_no" => $data['other_no']??"",
                ]
            ]);
        }
        return json_encode([
            'status' => 2,
            'message' => $return['message']
        ]);
    }

    public static function gtxy_query($order, Store $store, string $c_o, $that): string
    {
        //店铺数据
        $store_id = $store->store_id;
        $config_id = $order->config_id;
        if (empty($config_id)) {
            $config_id = $store->config_id;
        }
        try {
            list($mchNo, $config) = Config::config($store_id, $config_id, $order->company);
        } catch (\Exception $e) {
            return json_encode([
                "status" => 2,
                "message" => $e->getMessage()
            ]);
        }
        $resultVo = Pay::orderQuery($order, [
            "agetId" => $config->platform_id,
            "custId" => $mchNo,
            "public_key" => $config->public_key
        ]);
        if ($resultVo->getCode() == $resultVo->codeMap["ok"]) {
            switch ($resultVo->getData()["pay_status"]) {
                case 1:
                    $return = [
                        "status" => 1,
                        "pay_status" => 1,
                        "message" => $resultVo->getMsg(),
                        "data" => $resultVo->getData()
                    ];
                    break;
                case 2:
                    $return = [
                        "status" => 2,
                        "pay_status" => 1,
                        "message" => $resultVo->getMsg(),
                        "data" => $resultVo->getData()
                    ];
                    break;
                case 3:
                    $return = [
                        "status" => 3,
                        "pay_status" => 3,
                        "message" => $resultVo->getMsg(),
                        "data" => $resultVo->getData()
                    ];
                    break;
                default:
                    $return = [
                        "status" => 3,
                        "pay_status" => 3,
                        "message" => $resultVo->getMsg(),
                        "data" => $resultVo->getData()
                    ];
            }

        } else {
            $return = [
                "status" => 3,
                "message" => $resultVo->getMsg()
            ];
        }
        Log::channel("gtxy")->info("query-biz_return", $return);
        if ($return['status'] == '1') {
//            $trade_no = $return['data']['trade_no'] ?? ""; //系统订单号
            $trade_no = $return["data"]["other_no"] ?? ""; //国通落单号 20250911SSSr8q52
            $pay_time = (isset($return['data']['pay_time']) && !empty($return['data']['pay_time'])) ? date('Y-m-d H:i:m', strtotime($return['data']['pay_time'])) : ''; //支付完成时间，格式为 yyyyMMddhhmmss，如 2009年12月27日9点10分10秒表示为 20091227091010
            $payamt = isset($return['data']['netrAmt']) ? ($return['data']['netrAmt'] / 100) : ''; //实付金额，单位分
            $buyer_logon_id = $return["data"]["openId"] ?? "";
            $user_info = $return["data"]["openId"] ?? "";

            //改变数据库状态
            if ($order->pay_status != 1) {
                \App\Common\PaySuccessAction::addCoupon($order->out_trade_no, $resultVo->getData()["promotionDetail"] ?? "", 'query');
                Cache::forget($c_o);
                $insert_data = [
                    'status' => '1',
                    'pay_status' => 1,
                    'pay_status_desc' => '支付成功',
                    'buyer_id' => $user_info,
                    'buyer_logon_id' => $buyer_logon_id,
                    'trade_no' => $trade_no,
                    "other_no" => $order->other_no??"",
                    'pay_time' => $pay_time,
                    'buyer_pay_amount' => $payamt,
                ];
                $that->update_day_order($insert_data, $order->out_trade_no);
                //支付成功后的动作
                $data = [
                    'ways_type' => $order->ways_type,
                    'company' => $order->company,
                    'ways_type_desc' => $order->ways_type_desc,
                    'source_type' => '', //返佣来源
                    'source_desc' => 'gtxy', //返佣来源说明
                    'total_amount' => $order->total_amount,
                    'out_trade_no' => $order->out_trade_no,
                    'rate' => $order->rate,
                    'fee_amount' => $order->fee_amount,
                    'merchant_id' => $order->merchant_id,
                    'store_id' => $order->store_id,
                    'user_id' => $order->user_id,
                    'config_id' => $store->config_id,
                    'store_name' => $order->store_name,
                    'ways_source' => $order->ways_source,
                    'pay_time' => $pay_time,
                    'device_id' => isset($order->device_id) ? $order->device_id : "",
                ];
                PaySuccessAction::action($data);
            }
            return json_encode([
                'status' => '1',
                'pay_status' => '1',
                'message' => '支付成功',
                'data' => [
                    'ways_source' => $order->ways_source,
                    'pay_time' => $pay_time,
                    'out_trade_no' => $order->out_trade_no,
                    'pay_amount' => $payamt,
                    'total_amount' => $order->total_amount,
                    "other_no" => $order->other_no??"",
                    'trade_no' => $trade_no
                ]
            ]);
        } elseif ($return['status'] == '2') {
            return json_encode([
                'status' => '1',
                'pay_status' => 2,
                'message' => '待支付',
                'data' => [
                    'out_trade_no' => $order->out_trade_no,
                    'ways_type' => $order->ways_source,
                    'total_amount' => $order->total_amount,
                    'store_id' => $order->store_id,
                    'store_name' => $order->store_name,
                    'config_id' => $order->config_id,
                    'ways_source' => $order->ways_source,
                    "other_no" => $order->other_no??"",
                ]
            ]);
        } elseif ($return['status'] == '3') {
            return json_encode([
                'status' => 1,
                'pay_status' => '3',
                'message' => '订单未支付',
                'data' => [
                    'out_trade_no' => $order->out_trade_no,
                    'pay_amount' => $order->total_amount,
                    'total_amount' => $order->total_amount,
                    "other_no" => $order->other_no??"",
                ]
            ]);
        } //其他情况
        else {
            return json_encode([
                'status' => 2,
                'pay_status' => 3,
                'message' => $return['message'],
                'data' => [
                    'out_trade_no' => $order->out_trade_no,
                    'pay_amount' => $order->pay_amount,
                    'total_amount' => $order->total_amount,
                    "other_no" => $order->other_no??"",
                ],
            ]);
        }
    }

    public static function gtxy_refund(Order $order, array $params, $that): string
    {
        //店铺数据
        $store_id = $params["store_id"];

        $config_id = $order->config_id;
        if (empty($config_id)) {
            $store = Store::query()->where("store_id", $store_id)->first();
            $config_id = $store->config_id;
        }
//        $mchNo = StoreMchService::getMchNo($store_id, "gtxy");
//        if (empty($mchNo) && !empty($store["pid"])) {
//            $storeP_store_id = Store::query()->where("id", $store["pid"])->value("store_id");
//            $mchNo = StoreMchService::getMchNo($storeP_store_id, "gtxy");
//        }
//        if (empty($mchNo)) {
//            return json_encode([
//                "status" => 2,
//                "message" => "国通商户号不存在"
//            ]);
//        }
        list($mchNo, $config) = Config::config($store_id, $config_id, $order->company);
        //发起
        $resultVo = Pay::refund($order, (float)$params["refund_amount"], [
            "agetId" => $config->platform_id,
            "custId" => $mchNo,
            "public_key" => $config->public_key
        ]);
        $return = [
            "status" => 0,
            "message" => $resultVo->getMsg()
        ];
        if ($resultVo->getCode() == $resultVo->codeMap["ok"] && $resultVo->getData()["pay_status"] == 6) {
            $return = [
                "status" => 1,
                "message" => $resultVo->getMsg()
            ];
        }

        if ($resultVo->getCode() == $resultVo->codeMap["ok"] && $resultVo->getData()["pay_status"] == 7) {
            $return = [
                "status" => 0,
                "message" => $resultVo->getMsg()
            ];
        }


        if ($resultVo->getCode() == $resultVo->codeMap["ok"] && $resultVo->getData()["pay_status"] == 8) {
            $return = [
                "status" => -1,
                "message" => $resultVo->getMsg()
            ];
        }

        Log::channel("gtxy")->info("refund-biz_return", [$resultVo->getData()]);
        //退款请求成功
        if ($return["status"] == 1) {
            \App\Common\PaySuccessAction::addCoupon($order->out_trade_no, "", 'refund');
            $insert_data = [
                'status' => 6,
                'pay_status' => 6,
                'pay_status_desc' => '已退款',
                'refund_amount' => $params["new_refund_amount"],
                'fee_amount' => $params["new_fee_amount"]
            ];
            $that->update_day_order($insert_data, $order->out_trade_no);
            RefundOrder::create([
                'ways_source' => $order->ways_source,
                'type' => $params["ways_type"],
                'refund_amount' => $params["refund_amount"], //退款金额
                'refund_no' => $params["refund_no"] ?? "", //退款单号
                "other_refund_no" => $resultVo->getData()["refund_no"],
                'store_id' => $store_id,
                'merchant_id' => $params["merchant_id"],
                'out_trade_no' => $order->out_trade_no,
                'trade_no' => $resultVo->getData()["trade_no"],//国通的退款单号-  用于国通退款订单查询
            ]);
            Log::channel("gtxy")->info("RefundOrder::create", [
                'ways_source' => $order->ways_source,
                'type' => $params["ways_type"],
                'refund_amount' => $params["refund_amount"], //退款金额
                'refund_no' => $params["refund_no"] ?? "", //退款单号
                "other_refund_no" => $resultVo->getData()["refund_no"],
                'store_id' => $store_id,
                'merchant_id' => $params["merchant_id"],
                'out_trade_no' => $order->out_trade_no,
                'trade_no' => $resultVo->getData()["trade_no"],//国通的退款单号-  用于国通退款订单查询
            ]);
            //退款成功后的操作
            RefundSuccessAction::action([
                'out_trade_no' => $order->out_trade_no,
                'refund_no' => $params["refund_no"], //平台退款单号
            ]);
            $data = [
                'refund_amount' => $params["refund_amount"],
                'out_trade_no' => $order->out_trade_no,
                'refund_no' => $params["refund_no"] ?? "",//退款单号
                'other_no' => $order->trade_no
            ];

            //返佣去掉
            UserWalletDetail::where('out_trade_no', $order->out_trade_no)->update([
                'settlement' => '03',
                'settlement_desc' => '退款订单',
            ]);
            MerchantWalletDetail::where('out_trade_no', $order->out_trade_no)->update([
                'settlement' => '03',
                'settlement_desc' => '退款订单',
            ]);

            return json_encode([
                'status' => 1,
                'message' => '退款成功',
                'data' => $data,
            ]);
        } else if ($return["status"] == 0) {
            RefundOrderDoing::create([
                "company" => $order->company,
                'ways_source' => $order->ways_source,
                'type' => $params["ways_type"],
                'refund_amount' => $params["refund_amount"], //退款金额
                'refund_no' => $params["refund_no"] ?? "", //退款单号
                "other_refund_no" => $resultVo->getData()["refund_no"] ?? "",
                'store_id' => $store_id,
                'merchant_id' => $params["merchant_id"],
                'out_trade_no' => $order->out_trade_no,
                'trade_no' => $resultVo->getData()["trade_no"] ?? "",//国通的退款单号-  用于国通退款订单查询
            ]);
            return json_encode([
                'status' => 2,
                'message' => '退款中',
                'data' => [],
            ]);
        } else {
            //其他情况
            return json_encode([
                'status' => 2,
                'message' => $return['message']
            ]);
        }
    }


    //主扫逻辑
    public static function qr_submit(array $params, string $config_id, $ways_type)
    {
        try {
            $company = "gtxy";
            if (in_array($ways_type, [62011, 62012, 62014])) {
                $company = "gtxy_v2";
            }
            //获取电子码地址
            list($mchNo, $config) = Config::config((string)$params["store_id"], $config_id, $company);
            $reqData = [
                "orderNo" => $params["out_trade_no"],//用于调用查询接口时，写入服务商订单号（第三方订单号）使用
                "txamt" => bcmul((string)$params["total_amount"], (string)100),//元
            ];
            $resultVo = Pay::getCodeUrl($reqData, [
                "agetId" => $config->platform_id,
                "custId" => $mchNo,
                "public_key" => $config->public_key
            ]);
            if ($resultVo->getCode() == $resultVo->codeMap["ok"]) {
                $result = [
                    'status' => 1,
                    'message' => $resultVo->getMsg(),
                    'data' => [
                        'codeUrl' => $resultVo->getData()["url"]
                    ]
                ];
            } else {
                return [
                    'status' => 3,
                    'message' => $resultVo->getMsg(),
                ];
            }
            return $result;
        } catch (\Exception $ex) {
            if ($ex instanceof BizException) {
                return [
                    'status' => 2,
                    'message' => $ex->getMessage(),
                ];
            }
            return [
                'status' => 3,
                'message' => $ex->getMessage() . ' | ' . $ex->getFile() . ' | ' . $ex->getLine(),
            ];
        }
    }

}